<?php

namespace app\common\business;

use app\common\model\Follow as FollowModel;
use app\common\model\Followtask as TaskModel;
use app\common\model\PropagandaEducationHistory as PEHModel;
use app\common\model\PushMessage as PushMessageModel;
use app\Request;
use catcher\exceptions\FailedException;
use MongoDB\BSON\ObjectId;
use app\common\model\DiseasePatientTask as PathModel;
use app\common\model\PatientInfo as PatientInfoModel;
use catchAdmin\permissions\model\Users as UserModel;

class Message
{
    /**
     * 处理异常短信消息
     * @param string $type 随访 Project，宣教 PropagandaEducation，复诊 Answers, 随访路径Path
     * @param string $task_id 任务id
     * @param array $patients 患者多个
     * @param string $pushName 推送任务名称
     * @param array $doctors 推送医生
     * @return bool
     */
    public function smsAbnormalInfo(string $type, string $task_id = '', array $patients = [], string $pushName = '', array $doctors = []): bool
    {
        //短信发送失败的患者
        $smsFail = [];
        foreach ($patients as $k => $v) {
            if ($v['status'] !== 1) {
                $smsFail[] = $v['patientId'];
            }
        }

        switch ($type) {
            case 'Project':
                try {
                    $where[] = ['task_id', '=', new ObjectId($task_id)];

                    //处理发短信失败的患者
                    if (!empty($smsFail)) {
                        $failWhere[] = ['patientId', 'in', $smsFail];
                        $failIds = (new FollowModel())->where($where)->where($failWhere)->field('id')->select();
                        $failDatas = [];
                        foreach ($failIds as $k => $v) {
                            $failDatas[] = [
                                'id' => $v['id'],
                                'smsStatus' => 2
                            ];
                        }

                        $task = (new TaskModel())->getOneData([['id', '=', $task_id]], 'taskname');

                        //推送消息
                        $messageDatas = [
                            'type' => 1,
                            'typeName' => '随访',
                            'pushtime' => date('Y-m-d'),
                            'pushdatetime' => date('Y-m-d H:i:s'),
                            'creator_id' => $doctors[0]['id'],
                            'creator_name' => $doctors[0]['username'],
                            'task_id' => $task_id,
                            'title' => $task['taskname'],
                            'content' => '您好' . $doctors[0]['username'] . '，您推送的' . $task['taskname'] . '，短信发送失败！',
                            'created_at' => time(),
                            'deleted_at' => 0,
                            'isview' => 0,
                            'category' => 'Doctor'
                        ];
                        (new PushMessageModel())->save($messageDatas);
                        (new FollowModel())->saveAll($failDatas);
                    }
                } catch (\Exception $exception) {
                    throw new FailedException($exception->getMessage());
                }
                break;
            case 'PropagandaEducation':
                try {
                    $where[] = ['batch_no', '=', $task_id];

                    //处理发短信失败的患者
                    if (!empty($smsFail)) {
                        $failWhere[] = ['patientId', 'in', $smsFail];
                        $failIds = (new PEHModel())->where($where)->where($failWhere)->field('id,batch_name')->select();
                        $failDatas = [];
                        foreach ($failIds as $k => $v) {
                            $failDatas[] = [
                                'id' => $v['id'],
                                'status' => 0
                            ];
                        }

                        //推送消息
                        $messageDatas = [
                            'type' => 2,
                            'typeName' => '宣教',
                            'pushtime' => date('Y-m-d'),
                            'pushdatetime' => date('Y-m-d H:i:s'),
                            'creator_id' => $doctors[0]['id'],
                            'creator_name' => $doctors[0]['username'],
                            'task_id' => $task_id,
                            'title' => $failIds[0]['batch_name'],
                            'content' => '您好' . $doctors[0]['username'] . '，您推送的' . $failIds[0]['batch_name'] . '，短信发送失败！',
                            'created_at' => time(),
                            'deleted_at' => 0,
                            'isview' => 0,
                            'category' => 'Doctor'
                        ];
                        (new PushMessageModel())->save($messageDatas);
                        (new PEHModel())->saveAll($failDatas);
                    }
                } catch (\Exception $exception) {
                    throw new FailedException($exception->getMessage());
                }
                break;
            case 'Answers':
                break;
            case 'Path':
                $pathTask = (new PathModel())->where('id', $task_id)->field('doctors,disease_name')->find();

                //处理发短信失败的患者
                if (!empty($smsFail)) {
                    $failWhere[] = ['patientId', 'in', $smsFail];
                    $failPatients = (new PatientInfoModel())->where($failWhere)->column('name');
                    $patients = implode(', ', $failPatients);
                    //推送消息
                    $messageDatas = [];

                    foreach ($pathTask['doctors'] as $k => $v) {
                        $messageDatas[] = [
                            'type' => 8,
                            'typeName' => '自动随访',
                            'pushtime' => date('Y-m-d'),
                            'pushdatetime' => date('Y-m-d H:i:s'),
                            'creator_id' => $v['doctor_id'],
                            'creator_name' => $v['doctor_name'],
                            'task_id' => $task_id,
                            'title' => $pathTask['disease_name'],
                            'content' => '您好' . $v['doctor_name'] . '，您的随访路径任务' . $pathTask['disease_name'] . '，为(' . $patients . ')推送的' . $pushName . '，短信发送失败！',
                            'created_at' => time(),
                            'deleted_at' => 0,
                            'isview' => 0,
                            'category' => 'Doctor'
                        ];
                    }
                    (new PushMessageModel())->saveAll($messageDatas);
                }
                break;
            case 'Other':
                $patient = (new PatientInfoModel())->where('patientId', $patients[0])->field('name,timeLine')->find();

                if (!empty($patient['timeLine'])) {

                    //推送消息
                    $messageDatas = [
                        'type' => 9,
                        'typeName' => '其他',
                        'pushtime' => date('Y-m-d'),
                        'pushdatetime' => date('Y-m-d H:i:s'),
                        'creator_name' => $patient['timeLine'][0]['doctorName'],
                        'title' => '健康检测',
                        'content' => '您好' . $patient['timeLine'][0]['doctorName'] . '，您的患者' . $patient['name'] . $pushName . '测量异常，请进行跟踪！',
                        'created_at' => time(),
                        'deleted_at' => 0,
                        'isview' => 0,
                        'category' => 'Doctor'
                    ];

                    //医生id是否存在
                    if (empty($patient['timeLine'][0]['doctorId'])) {
                        $userId = (new UserModel())->where('doctor_code', $patient['timeLine'][0]['doctorNo'])->value('id');
                        $messageDatas['creator_id'] = $userId ?? '';
                    } else {
                        $messageDatas['creator_id'] = $patient['timeLine'][0]['doctorId'];
                    }
                    (new PushMessageModel())->save($messageDatas);
                }
                break;
            default:
                throw new FailedException("类型参数错误");
        }
        return true;
    }

    /**
     * 后台消息统计
     * @retrun array
     */
    public function getMessageStatistics(): array
    {
        $userInfo = request()->user();

        //全部类型消息
        $allWhere[] = ['creator_id', '=', $userInfo['id']];
        $allWhere[] = ['category', '=', 'Doctor'];
        $allCurrent = (new PushMessageModel())->getCount($allWhere);//全时间段计数
        $allWhere[] = ['pushtime', '<', date('Y-m-d')];
        $allYesterday = (new PushMessageModel())->getCount($allWhere);//昨天计数

        //随访消息
        $followWhere[] = ['creator_id', '=', $userInfo['id']];
        $followWhere[] = ['category', '=', 'Doctor'];
        $followWhere[] = ['type', '=', 1];
        $followCurrent = (new PushMessageModel())->getCount($followWhere);//全时间段计数
        $followWhere[] = ['pushtime', '<', date('Y-m-d')];
        $followYesterday = (new PushMessageModel())->getCount($followWhere);//昨天计数

        //宣教消息
        $edWhere[] = ['creator_id', '=', $userInfo['id']];
        $edWhere[] = ['category', '=', 'Doctor'];
        $edWhere[] = ['type', '=', 2];
        $edCurrent = (new PushMessageModel())->getCount($edWhere);//全时间段计数
        $edWhere[] = ['pushtime', '<', date('Y-m-d')];
        $edYesterday = (new PushMessageModel())->getCount($edWhere);//昨天计数

        return [
            'all' => [
                'total' => $allCurrent,
                'new' => $allCurrent - $allYesterday
            ],
            'follow' => [
                'total' => $followCurrent,
                'new' => $followCurrent - $followYesterday
            ],
            'ed' => [
                'total' => $edCurrent,
                'new' => $edCurrent - $edYesterday
            ]
        ];
    }

    /**
     * 存储消息
     * @param int $type 消息类型
     * @param string $task_id 任务id
     * @param string $task_name 任务名称
     * @param string $patientId 患者id
     * @param string $patientName 患者姓名
     * @param array $param 附加参数
     * @return bool
     */
    public function saveMessage(int $type, string $task_id, string $task_name, string $patientId, string $patientName, array $param = [], $isAuto = true): bool
    {


        if (empty($type) || empty($task_name)) {
            throw new FailedException("缺少参数");
        }

        //类型名称
        $typeName = config('dictionary.message_type');

        $data = [
            'type' => $type,
            'typeName' => $typeName[$type],
            'task_id' => $task_id,
            'task_name' => $task_name,
            'patientId' => $patientId,
            'content' => "您好" . $patientName . ",为您推送" . $task_name . "内容",
            'creator_id' => $isAuto === false ? request()->user()->id : 0,
            'pushtime' => date("Y-m-d"),
            'pushdatetime' => date("Y-m-d H:i:s"),
            'isview' => 0,
            'category' => "Patient",
            'deleted_at' => 0
        ];
        if ($type == 4) {
            $data["content"] = "您好:" . $patientName . '您有一条复诊任务:'.$task_name;
        }
        if (!empty($param)) {
            $data = array_merge($data, $param);
        }
        $ret = (new PushMessageModel())->addData($data);

        if (!$ret) {
            throw new FailedException("消息推送失败");
        }
        return true;
    }

}